/**
  **************************************************************************
  * @file     at32f421_int.c
  * @brief    main interrupt service routines.
  **************************************************************************
  *                       Copyright notice & Disclaimer
  *
  * The software Board Support Package (BSP) that is made available to
  * download from Artery official website is the copyrighted work of Artery.
  * Artery authorizes customers to use, copy, and distribute the BSP
  * software and its related documentation for the purpose of design and
  * development in conjunction with Artery microcontrollers. Use of the
  * software is governed by this copyright notice and the following disclaimer.
  *
  * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  *
  **************************************************************************
  */

/* includes ------------------------------------------------------------------*/
#include "./User/ADC/inc/adc_ctrl.h"
#include "./User/Beep/inc/beep_logic.h"
#include "./User/Debug/inc/debug_ctrl.h"
#include "./User/Key/inc/key_ctrl.h"
#include "./User/LED/inc/led_logic.h"
#include "./User/RS485/inc/rs485_ctrl.h"
#include "./User/Step_Motor/inc/step_motor_ctrl.h"
#include "at32f421_int.h"

/** @addtogroup AT32F421_periph_template
  * @{
  */

/** @addtogroup 421_LED_toggle
  * @{
  */

/**
  * @brief  this function handles nmi exception.
  * @param  none
  * @retval none
  */
void NMI_Handler(void)
{
}

/**
  * @brief  this function handles hard fault exception.
  * @param  none
  * @retval none
  */
void HardFault_Handler(void)
{
  /* go to infinite loop when hard fault exception occurs */
  while(1)
  {
  }
}

/**
  * @brief  this function handles memory manage exception.
  * @param  none
  * @retval none
  */
void MemManage_Handler(void)
{
  /* go to infinite loop when memory manage exception occurs */
  while(1)
  {
  }
}

/**
  * @brief  this function handles bus fault exception.
  * @param  none
  * @retval none
  */
void BusFault_Handler(void)
{
  /* go to infinite loop when bus fault exception occurs */
  while(1)
  {
  }
}

/**
  * @brief  this function handles usage fault exception.
  * @param  none
  * @retval none
  */
void UsageFault_Handler(void)
{
  /* go to infinite loop when usage fault exception occurs */
  while(1)
  {
  }
}

/**
  * @brief  this function handles svcall exception.
  * @param  none
  * @retval none
  */
//void SVC_Handler(void)
//{
//}

/**
  * @brief  this function handles debug monitor exception.
  * @param  none
  * @retval none
  */
void DebugMon_Handler(void)
{
}

/**
  * @brief  this function handles pendsv_handler exception.
  * @param  none
  * @retval none
  */
//void PendSV_Handler(void)
//{
//}

/**
  * @brief  this function handles systick handler.
  * @param  none
  * @retval none
  */
//void SysTick_Handler(void)
//{
//}

/**
  * @}
  */

/**
  * @}
  */

void ADC_DMA_HANDLE(void)
{
    if(dma_flag_get(ADC_DMA_FDT_FLAG))
    {
        temperature = (1.26 - (double)adcData[ADC_CH_TEMPERATURE_INDEX] * 3.3 / 4096) / (-0.00423) + 25;
        vRef = ((double)1.2 * 4095) / adcData[ADC_CH_VREF_INDEX];
        
        dma_flag_clear(ADC_DMA_FDT_FLAG);
    }
}


void BEEP_TMR_HANDLE(void)
{
    if(tmr_interrupt_flag_get(BEEP_TMR, TMR_OVF_FLAG))
    {
        if(--beepOnMsCnt == 0)
        {
            beep_off();
            tmr_counter_enable(BEEP_TMR, FALSE);
        }
        
        tmr_flag_clear(BEEP_TMR, TMR_OVF_FLAG);
    }
}


void DEBUG_USART_HANDLE(void)
{
    if(usart_flag_get(DEBUG_USART, USART_RDBF_FLAG))
    {
        if(debugUsartRxFinishFlag == 0 && debugUsartRxIndex < DEBUG_USART_RX_BUFFER_LEN)
        {
            debugUsartRxBuffer[debugUsartRxIndex++] = usart_data_receive(DEBUG_USART);
        }
        else
        {
            usart_flag_clear(DEBUG_USART, USART_RDBF_FLAG);
        }
    }
    
    if(usart_flag_get(DEBUG_USART, USART_IDLEF_FLAG))
    {
        usart_data_receive(DEBUG_USART);
        debugUsartRxFinishFlag = 1;
    }
}


void KEY_TMR_HANDLE(void)
{
    if(tmr_interrupt_flag_get(KEY_TMR, TMR_OVF_FLAG))
    {
        for(uint8_t i = 0; i < KEY_NUM; i++)
        {
            if(key[i].longPressScanFlag && ++key[i].longPressJudgeCnt >= key[i].longPressJudgeNum)
            {
                key[i].longPressScanFlag = 0;
                key[i].longPressJudgeCnt = 0;
                key[i].state = KEY_STATE_CLICK_LONG;
                
                if(key[i].handle == KEY_HANDLE_NONE)
                {
                    key[i].handle = KEY_HANDLE_LONG;
                    beep_alarm(keyLongBeep);
                }
            }
        }
        
        tmr_flag_clear(KEY_TMR, TMR_OVF_FLAG);
    }
}


void LED1_TMR_HANDLE(void)
{
    if(tmr_interrupt_flag_get(LED1_TMR, TMR_OVF_FLAG))
    {
        if(led1.mode == !!LED_MODE_BREATH)
        {
            if(led1.breathDir)
            {
                if(led1.tmrCurrentPulse < LED1_TMR_PULSE && LED1_TMR_PULSE - led1.tmrCurrentPulse >= led1.breathStep)
                {
                    led1.tmrCurrentPulse += led1.breathStep;
                }
                else
                {
                    led1.tmrCurrentPulse = LED1_TMR_PULSE;
                    led1.breathDir = 0;
                }
            }
            else
            {
                if(led1.tmrCurrentPulse > 0 && led1.tmrCurrentPulse >= led1.breathStep)
                {
                    led1.tmrCurrentPulse -= led1.breathStep;
                }
                else
                {
                    led1.tmrCurrentPulse = 0;
                    led1.breathDir = 1;
                }
            }
            
            tmr_channel_value_set(led1.tmr, led1.tmrCh, led1.tmrCurrentPulse);
        }
        else
        {
            if(++led1.blinkCnt >= led1.blinkNum)
            {
                led1.blinkCnt = 0;
                led_blink(&led1);
            }
            
        }
        
        tmr_flag_clear(LED1_TMR, TMR_OVF_FLAG);
    }
}


void LED2_TMR_HANDLE(void)
{
    if(tmr_interrupt_flag_get(LED2_TMR, TMR_OVF_FLAG))
    {
        if(led2.mode == !!LED_MODE_BREATH)
        {
            if(led2.breathDir)
            {
                if(led2.tmrCurrentPulse < LED2_TMR_PULSE && LED2_TMR_PULSE - led2.tmrCurrentPulse >= led2.breathStep)
                {
                    led2.tmrCurrentPulse += led2.breathStep;
                }
                else
                {
                    led2.tmrCurrentPulse = LED2_TMR_PULSE;
                    led2.breathDir = 0;
                }
            }
            else
            {
                if(led2.tmrCurrentPulse > 0 && led2.tmrCurrentPulse >= led2.breathStep)
                {
                    led2.tmrCurrentPulse -= led2.breathStep;
                }
                else
                {
                    led2.tmrCurrentPulse = 0;
                    led2.breathDir = 1;
                }
            }
            
            tmr_channel_value_set(led2.tmr, led2.tmrCh, led2.tmrCurrentPulse);
        }
        else
        {
            if(++led2.blinkCnt >= led2.blinkNum)
            {
                led2.blinkCnt = 0;
                led_blink(&led2);
            }
            
        }
        
        tmr_flag_clear(LED2_TMR, TMR_OVF_FLAG);
    }
}


void RS485_USART_HANDLE(void)
{
    if(usart_flag_get(RS485_USART, USART_RDBF_FLAG))
    {
        if(rs485UsartRxFinishFlag == 0 && rs485UsartRxIndex < RS485_USART_RX_BUFFER_LEN)
        {
            rs485UsartRxBuffer[rs485UsartRxIndex++] = usart_data_receive(RS485_USART);
        }
        else
        {
            usart_flag_clear(RS485_USART, USART_RDBF_FLAG);
        }
    }
    
    if(usart_flag_get(RS485_USART, USART_IDLEF_FLAG))
    {
        usart_data_receive(RS485_USART);
        rs485UsartRxFinishFlag = 1;
    }
}
